package br.com.andre.neo4j.model;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;

public class RelationshipCreate {
	private Connection conn;
	
	public RelationshipCreate() {
		this.conn = new Connection();
	}
	
	public void relationshipUserAndMovie(UserTO user, MovieTO movie){
		GraphDatabaseService graph = conn.newConnection();
		Index<Relationship> index = graph.index().forRelationships("watched");
		Relationship relationship = index.get("log", user.getLogin() + movie.getTitle()).getSingle();

		Node nodeUser = getNodeUser(user, graph);
		Node nodeMovie = getNodeMovie(movie, graph);
		
		if (nodeUser == null) {
			System.out.println("Este usuario não existe");
		}else if (nodeMovie == null) {
			System.out.println("Este filme não existe");
		} else 	if (relationship == null) {
			Transaction tx = graph.beginTx();
			try {
				
				relationship = nodeUser.createRelationshipTo(nodeMovie, RelType.WATCHED);
				index.add(relationship, "log", user.getLogin() + movie.getTitle());
				tx.success();
				System.out.println("Relationship saved!");
			} catch (Exception e) {
				tx.failure();
			}finally{
				tx.finish();
			}
			
		}else{
			System.out.println("The user " + user.getName() + " has already watched the movie " + movie.getTitle() + "!");
		}
		graph.shutdown();
	}
	
	public void relationshipActorAndMovieAndDirector(MovieTO movie, ActorTO actor, DirectorTO director){
		GraphDatabaseService graph = conn.newConnection();
		Index<Relationship> indexServed = graph.index().forRelationships("served");
		Index<Relationship> indexDirected = graph.index().forRelationships("directed");
		Relationship relationshipServed = indexServed.get("log", actor.getName() + movie.getTitle()).getSingle();
		Relationship relationshipDirected = indexDirected.get("log",director.getName() + movie.getTitle()).getSingle();

		Node nodeMovie = getNodeMovie(movie, graph);
		Node nodeActor = getNodeActor(actor, graph);
		Node nodeDirector = getNodeDirector(director, graph);
		
		if (relationshipServed == null) {
			Transaction tx = graph.beginTx();
			try {
				
				relationshipServed = nodeActor.createRelationshipTo(nodeMovie, RelType.SERVED);
				indexServed.add(relationshipServed, "log", actor.getName() + movie.getTitle());
				tx.success();
				System.out.println("RelationshipServed saved!");
			} catch (Exception e) {
				tx.failure();
			}finally{
				tx.finish();
			}
			
		}else{
			System.out.println("The actor " + actor.getName() + " has already served the movie " + movie.getTitle() + "!");
		}
		if (relationshipDirected == null) {
			Transaction tx = graph.beginTx();
			try {
				
				relationshipDirected = nodeDirector.createRelationshipTo(nodeMovie, RelType.DIRECTED);
				indexDirected.add(relationshipDirected, "log", director.getName() + movie.getTitle());
				tx.success();
				System.out.println("RelationshipDirected saved!");
			} catch (Exception e) {
				tx.failure();
			}finally{
				tx.finish();
			}
			
		}else{
			System.out.println("The director " + director.getName() + " has already directed the movie " + movie.getTitle() + "!");
		}		
		
		graph.shutdown();
	}
	
	private Node getNodeMovie(MovieTO movie, GraphDatabaseService graph) {
		Index<Node> index = graph.index().forNodes("movie");
		Node node = index.get("title", movie.getTitle()).getSingle();
		return node;
	}
	private Node getNodeUser(UserTO user, GraphDatabaseService graph) {
		Index<Node> index = graph.index().forNodes("user");
		Node node = index.get("login", user.getLogin()).getSingle();
		return node;
	}
	
	private Node getNodeActor(ActorTO actor, GraphDatabaseService graph) {
		Index<Node> index = graph.index().forNodes("actor");
		Node node = index.get("name", actor.getName()).getSingle();
		return node;
	}
	
	private Node getNodeDirector(DirectorTO director, GraphDatabaseService graph) {
		Index<Node> index = graph.index().forNodes("director");
		Node node = index.get("name", director.getName()).getSingle();
		return node;
	}
	
}